package com.bro.person;

import cn.org.rapid_framework.generator.GeneratorFacade;
import com.bro.person.base.utils.FileUtil;
import com.bro.person.generator.XMLUtil;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.api.VerboseProgressCallback;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/**
 * 自动生成service代码
 *
 * @author swallow
 */
public class GenCode {
	private static final Logger logger = LoggerFactory.getLogger(GenCode.class);

	/** 读取资源配置 */
	static ResourceBundle resource = ResourceBundle.getBundle("generator");
	static String projectName = resource.getString("projectName");
	static String serviceOutRootDir = resource.getString("serviceOutRootDir");
	static String controllerOutRootDir = resource.getString("controllerOutRootDir");
	static String[] tableNames = resource.getString("tableNames").split(",");

	public static void main(String[] args) throws Exception {
		logger.info("[GenCode][main]entering,tableNames:{},projectName:{}", tableNames, projectName);
		// 表名数组
		// 读取配置文件，更新mybatis generator生成所需的xml文件
		XMLUtil.updateMybatisGeneratorXML(tableNames);

		// 使用mybatis generateor 生成model和criteria等文件，需要修改对应的gencode.properties文件
		genByMyBatisGenerator();

		// 生成mapper接口,每次生成实体之后均需执行该方法，以保证mapper正常
		genMapper(tableNames);
//		// 生成DB操作service
		genService(tableNames,serviceOutRootDir);
		// 生成DB操作controller
		genController(tableNames,controllerOutRootDir);

	}

	/**
	 * 使用模板生成代码基础方法
	 *
	 * @param tableNames
	 *            表名数组
	 * @param broTemplateName
	 *            模板名称
	 * @param outRootDir
	 *            输出路径
	 * @throws Exception
	 */
	private static void genByTemplate(String[] tableNames, String broTemplateName, String outRootDir)
			throws Exception {
		// 指定模板读取路径
		String templatePath = ClassLoader.getSystemResource(broTemplateName).toString();
		GeneratorFacade g = new GeneratorFacade();
		g.getGenerator().addTemplateRootDir(templatePath);
		// 有外部的输出路径，覆盖之
		if (StringUtils.isNotBlank(outRootDir)) {
			g.getGenerator().setOutRootDir(outRootDir);
		}
		// 兼容处理文件路径
		outRootDir = g.getGenerator().getOutRootDir();
		outRootDir = FileUtil.getRealFilePath(outRootDir);
		g.getGenerator().setOutRootDir(outRootDir);
		// 通过数据库表生成文件
		g.generateByTable(tableNames);
	}

	/**
	 * 使用模板生成代码，生成目标路径为generateor.xml中配置的路径
	 *
	 * @param tableNames
	 * @param broTemplateName
	 * @throws Exception
	 */
	private static void genByTemplate(String[] tableNames, String broTemplateName) throws Exception {
		genByTemplate(tableNames, broTemplateName, null);
	}

	/**
	 * 使用模板生成mapper代码
	 *
	 * @throws Exception
	 * @param tableNames
	 */
	private static void genMapper(String[] tableNames) throws Exception {
		genByTemplate(tableNames, "broMapperTemplate");
		logger.info("[GenCode][genMapper]生成mapper成功！tableNames:{}", tableNames);
	}

	/**
	 * 使用模板生成service代码
	 *
	 * @throws Exception
	 * @param tableNames
	 */
	private static void genService(String[] tableNames,String serviceOutRootDir) throws Exception {
		genByTemplate(tableNames, "broServiceTemplate",serviceOutRootDir);
		logger.info("[GenCode][genService]生成service成功！tableNames:{}", tableNames,serviceOutRootDir);
	}

	/**
	 * 使用模板生成controller代码
	 *
	 * @throws Exception
	 * @param tableNames
	 */
	private static void genController(String[] tableNames,String serviceOutRootDir) throws Exception {
		genByTemplate(tableNames, "broControllerTemplate",serviceOutRootDir);
		logger.info("[GenCode][genController]生成controller成功！tableNames:{}", tableNames,serviceOutRootDir);
	}

	/**
	 * 使用MyBatisGenerator生成model、criteria、mapper等文件
	 *
	 */
	private static void genByMyBatisGenerator() {
		List<String> warnings = new ArrayList<>();
		try {
			String configFilePath = ClassLoader.getSystemResource("generatorConfig.xml").getPath();
			logger.debug("[GenCode][genByMyBatisGenerator]加载MyBatisGenerator配置文件,path:{}", configFilePath);
			boolean overwrite = true;
			File configFile = new File(configFilePath);
			ConfigurationParser cp = new ConfigurationParser(warnings);
			Configuration config = cp.parseConfiguration(configFile);
			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
			MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
			ProgressCallback progressCallback = new VerboseProgressCallback();
			myBatisGenerator.generate(progressCallback);
		} catch (Exception e) {
			e.printStackTrace();
		}
		for (String warning : warnings) {
			logger.debug("[GenCode][genByMyBatisGenerator]warning:{}", warning);
		}
	}
}
